#import "SyncRequest.h"
#import "SBJson.h"
#import "iShopAppDelegate.h"
#import "Category.h"
#import "NSDateExtension.h"
#import "NSManagedObjectExtenstion.h"
#import "Shop.h"
#import "Category.h"
#import "Utils.h"
#import "CoreDataUtils.h"
#import "Promotion.h"
#import "BaseProduct.h"

#define kShopEntity @"Shop"
#define kCategoryEntity @"Category"
#define kParentCategoryField @"ParentCategoryID"
//#define kShopEntity @"Shop"
//#define kShopEntity @"Shop"
//#define kShopEntity @"Shop"
//#define kShopEntity @"Shop"

@implementation SyncRequest

-(void) makeRequest
{
	NSMutableDictionary * dictionary = [NSMutableDictionary dictionary];
	[dictionary setObject:[((NSDate*)[Utils getValueForRefKey:kLastSync]) getJSONDateString] forKey:KLastSync];
	NSLog(@"%@",[dictionary JSONRepresentation]);
	[super requestTo:@"SyncData" withBody:[dictionary JSONRepresentation]];
}

-(void) processResult:(NSDictionary*)result
{
	iShopAppDelegate *appDelegate = (iShopAppDelegate*)[[UIApplication sharedApplication] delegate];
	NSDictionary *resultDict = [result valueForKey:@"SyncDataResult"];
	
	if (resultDict) {
		if ([[resultDict objectForKey:@"isSuccessful"] boolValue] == YES) {
			
		}
		else {
			//NSLog(@"notifyIfConnectionFail:%@",[error localizedDescription]);
			UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Login Fail" message:[resultDict objectForKey:@"ErrorMessage"] delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
			[alert show];
			[alert release];
			return;
		}
		
	}
	
	
	
	NSDate *currentDate = [NSDate getDateFromJSON:(NSString*)[resultDict objectForKey:@"SyncTime"]]; 
	[Utils setValue:currentDate forRefKey:kLastSync];
	NSLog(@"currentDate:%@",currentDate);
	
	NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
	[dateFormatter setLocale:[NSLocale currentLocale]];
	[dateFormatter setTimeStyle:NSDateFormatterLongStyle];
	[dateFormatter setDateStyle:NSDateFormatterLongStyle];
	
	NSString *dateString = [dateFormatter stringFromDate:currentDate];
	NSLog(@"NSDateFormatter String: %@", dateString);
	
	NSDate *dateObject = [dateFormatter dateFromString:dateString];
	NSLog(@"NSDateFormatter Object: %@", dateObject);
	

	NSMutableArray * orderParse = [[NSMutableArray alloc] initWithObjects:@"Shops",@"Categories",@"Brands",@"Promotions",@"BaseProducts",@"Comments",@"Products",@"SubProducts",@"BaseProductImages",nil]; 
	NSMutableArray * orderEntity = [[NSMutableArray alloc] initWithObjects:@"Shop",@"Category",@"Brand",@"Promotion",@"BaseProduct",@"Comment",@"Product",@"SubProduct",@"BaseProductImage",nil]; 
	NSMutableArray * orderEntityID = [[NSMutableArray alloc] initWithObjects:@"ShopID",@"CategoryID",@"BrandID",@"PromotionID",@"BaseProductID",@"CommentID",@"ProductID",@"SubProductID",nil];
	NSManagedObjectContext *context = [appDelegate managedObjectContext];
	
	//for category
	NSMutableArray *subCategoryObjs = [[NSMutableArray alloc] init];
	
 	for (int parseIndex = 0; parseIndex < orderParse.count; parseIndex++) {
		NSString *field = [orderParse objectAtIndex:parseIndex];
		NSLog(@"parse field:%@",field);
		NSArray *arrayObjects = [resultDict valueForKey:field];
		NSLog(@"arrayObjects:%@",arrayObjects);
		for (NSDictionary *itemDictionary in arrayObjects){
			
			@try {
				NSLog(@"itemDictionary:%@",itemDictionary);
				NSEntityDescription *entityDesc = [NSEntityDescription    
												   entityForName:[orderEntity objectAtIndex:parseIndex] inManagedObjectContext:context];
				
				NSManagedObject *object;
				int flag = [[itemDictionary objectForKey:@"Flag"] intValue];
				if (flag == 1) {
					object = [NSEntityDescription insertNewObjectForEntityForName:[orderEntity objectAtIndex:parseIndex] inManagedObjectContext:context];
				}
				else {
					if ([[orderEntity objectAtIndex:parseIndex] isEqualToString:@"BaseProductImage"]) {					
						NSDictionary *condition= [[NSMutableDictionary alloc] init];
						[condition setValue:[itemDictionary objectForKey:@"BaseProductID"] forKey:@"BaseProductID"];
						[condition setValue:[itemDictionary objectForKey:@"BaseProdImage"] forKey:@"BaseProdImage"];
						object = [CoreDataUtils getObjectEntity:@"BaseProductImage" fromCondition:condition];
					}
					else {
						
						NSFetchRequest *request = [[NSFetchRequest alloc] init];
						
						[request setEntity:entityDesc];
						NSString *fieldID = [orderEntityID objectAtIndex:parseIndex];
						NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K == %@",
											 
											 fieldID, [itemDictionary objectForKey:fieldID]];
						
						[request setPredicate:pred];
						
						NSError *error;
						
						NSArray *matching_objects = [context executeFetchRequest:request error:&error]; 
						
						if (matching_objects && matching_objects.count > 0) {
							object = [matching_objects lastObject];
						}
						else {
							NSLog(@"error");
							abort();
						}
						[request release];
					}

				}
				NSLog(@"FLAG:%i",flag);
				if (flag != -1) {					
					[object safeSetValuesForKeysWithDictionary:itemDictionary];
					
					//For Category: Parent vs Sub Category
					if ([[orderEntity objectAtIndex:parseIndex] isEqualToString:@"Category"]) {
						NSString *parentCategoryID = [itemDictionary objectForKey:kParentCategoryField];
						if ([parentCategoryID isKindOfClass:[NSString class]] && parentCategoryID.length > 0) {
							[subCategoryObjs addObject:object];
						}
					}
					
					
					//For Promotion: Shop vs Promotion
					if ([[orderEntity objectAtIndex:parseIndex] isEqualToString:@"Promotion"]) {					
						NSDictionary *condition= [[NSMutableDictionary alloc] init];
						[condition setValue:[itemDictionary objectForKey:@"ShopID"] forKey:@"ShopID"];
						NSManagedObject *shopObj = [CoreDataUtils getObjectEntity:@"Shop" fromCondition:condition];
						if (shopObj) {
							[((Shop*)shopObj) addPromotionsObject:(Promotion*)object];
						}
					}
					
					//For BaseProduct: baseproduct vs brand
					if ([[orderEntity objectAtIndex:parseIndex] isEqualToString:@"BaseProduct"]) {					
						NSDictionary *condition= [[NSMutableDictionary alloc] init];
						[condition setValue:[itemDictionary objectForKey:@"BrandID"] forKey:@"BrandID"];
						NSManagedObject *brandObj = [CoreDataUtils getObjectEntity:@"Brand" fromCondition:condition];
						if (brandObj) {
							[((Brand*)brandObj) addBaseProductsObject:(BaseProduct*)object];
						}
					}
					
					//For BaseProduct: baseproduct vs category
					if ([[orderEntity objectAtIndex:parseIndex] isEqualToString:@"BaseProduct"]) {					
						NSDictionary *condition= [[NSMutableDictionary alloc] init];
						[condition setValue:[itemDictionary objectForKey:@"CategoryID"] forKey:@"CategoryID"];
						NSManagedObject *categoryObj = [CoreDataUtils getObjectEntity:@"Category" fromCondition:condition];
						if (categoryObj) {
							[((Category*)categoryObj) addBaseProductsObject:(BaseProduct*)object];
						}
					}
					
					//For Comment: Comment vs baseproduct
					if ([[orderEntity objectAtIndex:parseIndex] isEqualToString:@"Comment"]) {					
						NSDictionary *condition= [[NSMutableDictionary alloc] init];
						[condition setValue:[itemDictionary objectForKey:@"BaseProductID"] forKey:@"BaseProductID"];
						NSManagedObject *baseProductObj = [CoreDataUtils getObjectEntity:@"BaseProduct" fromCondition:condition];
						if (baseProductObj) {
							[((BaseProduct*)baseProductObj) addCommentsObject:(Comment*)object];
						}
					}
					
					//For Product: Product vs Shop
					if ([[orderEntity objectAtIndex:parseIndex] isEqualToString:@"Product"]) {					
						NSDictionary *condition= [[NSMutableDictionary alloc] init];
						[condition setValue:[itemDictionary objectForKey:@"ShopID"] forKey:@"ShopID"];
						NSManagedObject *ShopObj = [CoreDataUtils getObjectEntity:@"Shop" fromCondition:condition];
						if (ShopObj) {
							[((Shop*)ShopObj) addProductsObject:(Product*)object];
						}
					}
					
					//For Product: Product vs Promotion
					if ([[orderEntity objectAtIndex:parseIndex] isEqualToString:@"Product"]) {					
						NSDictionary *condition= [[NSMutableDictionary alloc] init];
						[condition setValue:[itemDictionary objectForKey:@"PromotionID"] forKey:@"PromotionID"];
						NSManagedObject *PromotionObj = [CoreDataUtils getObjectEntity:@"Promotion" fromCondition:condition];
						if (PromotionObj) {
							[((Promotion*)PromotionObj) addProductsObject:(Product*)object];
						}
					}
					
					//For SubProduct: SubProduct vs Product
					if ([[orderEntity objectAtIndex:parseIndex] isEqualToString:@"SubProduct"]) {					
						NSDictionary *condition= [[NSMutableDictionary alloc] init];
						[condition setValue:[itemDictionary objectForKey:@"ProductID"] forKey:@"ProductID"];
						NSManagedObject *ProductObj = [CoreDataUtils getObjectEntity:@"Product" fromCondition:condition];
						if (ProductObj) {
							[((Product*)ProductObj) addSubProductsObject:(SubProduct*)object];
						}
					}
					
					//For Product: Product vs BaseProduct
					if ([[orderEntity objectAtIndex:parseIndex] isEqualToString:@"Product"]) {					
						NSDictionary *condition= [[NSMutableDictionary alloc] init];
						[condition setValue:[itemDictionary objectForKey:@"BaseProductID"] forKey:@"BaseProductID"];
						NSManagedObject *BaseProductObj = [CoreDataUtils getObjectEntity:@"BaseProduct" fromCondition:condition];
						if (BaseProductObj) {
							[((BaseProduct*)BaseProductObj) addProductsObject:(Product*)object];
						}
					}
					
					//For Product: Product vs BaseProduct
					if ([[orderEntity objectAtIndex:parseIndex] isEqualToString:@"BaseProductImage"]) {					
						NSDictionary *condition= [[NSMutableDictionary alloc] init];
						[condition setValue:[itemDictionary objectForKey:@"BaseProductID"] forKey:@"BaseProductID"];
						NSManagedObject *BaseProductObj = [CoreDataUtils getObjectEntity:@"BaseProduct" fromCondition:condition];
						if (BaseProductObj) {
							[((BaseProduct*)BaseProductObj) addBaseProductImagesObject:(BaseProductImage*)object];
						}
					}
				}
				else {
					[context deleteObject:object];				
				}
			}
			@catch (NSException * e) {
				NSLog(@"error:%@",[e description]);
			}	
		}
		
		if (subCategoryObjs.count > 0) {
			[CoreDataUtils updateCategory:subCategoryObjs];
			[subCategoryObjs removeAllObjects];
		}
	}
	[orderEntity release];
	[orderEntityID removeAllObjects];
	[orderEntityID release];
	[appDelegate saveContext];
	BOOL rsRet = YES;
	if (_delegate && [_delegate respondsToSelector:@selector(processRequestResult:)]) {
		[_delegate processRequestResult:rsRet];
	}
}

-(void) notifyIfConnectionFail:(NSError*)error
{
	NSLog(@"notifyIfConnectionFail:%@",[error localizedDescription]);
	BOOL rsRet = NO;
	if (_delegate && [_delegate respondsToSelector:@selector(processRequestResult:)]) {
		[_delegate processRequestResult:rsRet];
	}
}

@end
